"""
Author        yongfa
Date          2022-07-15 19:32:58
LastEditTime  2023-09-01 09:22:40
LastEditors   yongfa
Description   日志扩展
"""

import logging
import logging.config
import os
import time
import json

import coloredlogs
from flask import g, request
from app.modules.v1.system_logs.models import SystemLog

# os.path.abspath	获取绝对路径
# os.path.dirname	(__file__) 获取当前文件路径
# 项目根目录
ROOT_FOLDER_PATH = os.getcwd()  # 返回当前进程的工作目录

# 日志文件路径
LOG_FOLDER_PATH = os.path.join(ROOT_FOLDER_PATH, 'logs')
if not os.path.exists(LOG_FOLDER_PATH):
    os.makedirs(LOG_FOLDER_PATH)

# 实例化、配置 logger


def get_logger(logger_name):
    """
    logger 记录器
    可根据不同模块，获取不同的记录器
    """

    logger = logging.getLogger(logger_name)
    coloredlogs.install(level='DEBUG', logger=logger)
    return logger


def record_request_log(response, *args, **kwargs):
    # 记录请求日志
    try:
        now_time = time.time()
        request_start_time = getattr(g, 'request_start_time', None)
        user_id = g.get('user_id', None)
        request_param_json = request.get_json(silent=True)
        for _key in ['password', 'access_secret']:
            if request_param_json and request_param_json.get(_key) is not None:
                request_param_json[_key] = "******"   # 处理密码

        format_str = (
            '%(remote_addr)s request: [%(status_code)s] %(request_method)s, url: %(path)s, '
            'module: %(module)s, endpoint: %(endpoint)s, params: %(request_param)s',
            'request_start_time: %(request_start_time)s, response_time: %(response_time)s, '
            'user_id: %(user_id)s, message: %(message)s'
        )
        logger = get_logger('response')
        message = ''
        response_json = None
        try:
            response_json = response.json
        except json.JSONDecodeError as e:
            logger.info('response json 解析错误 ERROR: {}'.format(e))
        if response_json and hasattr(response_json, 'message'):
            message = str(response_json.get('message'))

        status_code = 0
        if response_json and hasattr(response_json, 'status_code'):
            status_code = int(str(response_json.get('status_code')))

        data = dict(
            remote_addr=request.headers.get('X-Real-Ip', request.environ.get('HTTP_X_REAL_IP', request.remote_addr)),

            status_code=status_code,
            request_method=request.method,
            path=request.full_path[:100],
            module=request.blueprint,
            endpoint=request.endpoint,
            request_param={'args': request.args, 'json': request_param_json},
            request_start_time=str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(request_start_time))),
            response_time=float("{:.3}".format(
                now_time - request_start_time if request_start_time is not None else 0.000)),
            user_id=user_id,
            message=message[:500]
        )

        if data['status_code'] == 1 or data.get('request_method') in ['POST', 'PUT', 'DELETE']:  # 错误请求或创建修改请求
            # if data.get('request_method') in ['POST', 'PUT', 'DELETE']:  # 创建修改请求
            SystemLog.create(**data)

        logger.info(format_str, data)

    except Exception as e:
        logger.exception('保存日志错误' + str(e))

    return response


DEFAULT_LOGGING_CONFIGS = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(threadName)s] [%(name)s:%(funcName)s] '
                      '[line:%(lineno)d] [%(levelname)s]- %(message)s'}
    },
    'handlers': {
        'error': {
            'level': 'ERROR',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(ROOT_FOLDER_PATH, 'logs', 'error.log'),
            # 'maxBytes': 1024 * 1024 * 5, # 按大小
            'when': 'midnight',  # 按每天午夜
            'backupCount': 7,
            'encoding': "UTF-8",
            'formatter': 'standard',
        },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'standard'
        },
        'access': {
            'level': 'WARNING',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(ROOT_FOLDER_PATH, 'logs', 'access.log'),
            # 'maxBytes': 1024 * 1024 * 5, # 按大小
            'when': 'midnight',  # 按每天午夜
            'backupCount': 7,
            'encoding': "UTF-8",
            'formatter': 'standard',
        },
        'celery': {
            'level': 'WARNING',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(ROOT_FOLDER_PATH, 'logs', 'celery.log'),
            # 'maxBytes': 1024 * 1024 * 5, # 按大小
            'when': 'midnight',  # 按每天午夜
            'backupCount': 7,
            'encoding': "UTF-8",
            'formatter': 'standard',
        }

    },
    'loggers': {
        'app': {
            'handlers': ['error', 'console'],
            'level': 'INFO',
            'propagate': False
        },
        'celery': {
            'handlers': ['celery', 'console'],
            'level': 'INFO',
            'propagate': False
        },
        'response': {
            'handlers': ['error', 'console', 'access'],
            'level': 'INFO',
            'propagate': False
        }
    }
}


# 配置日志
def configure_logging(app):
    """注册日志"""
    logging.config.dictConfig(DEFAULT_LOGGING_CONFIGS)
    app.after_request(record_request_log)
    app.logger = get_logger('app')
